﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace Ruleweaver
{
	[ContractClass(typeof(ICheckableContract))]
	public interface ICheckable
	{
		Type TargetType { get; }

		object Target { get; }

		bool Apply();
	}

	[ContractClass(typeof(ICheckableContract<>))]
	public interface ICheckable<out T> : ICheckable
	{
		new T Target { get; }
	}

	[ContractClassFor(typeof(ICheckable))]
	internal abstract class ICheckableContract : ICheckable
	{
		Type ICheckable.TargetType
		{
			get
			{
				Contract.Ensures(Contract.Result<Type>() != null);

				return null;
			}
		}

		object ICheckable.Target
		{
			get { return null; }
		}

		bool ICheckable.Apply()
		{
			return false;
		}
	}

	[ContractClassFor(typeof(ICheckable<>))]
	internal abstract class ICheckableContract<T> : ICheckable<T>
	{
		Type ICheckable.TargetType
		{
			get { return null; }
		}

		object ICheckable.Target
		{
			get { return null; }
		}

		T ICheckable<T>.Target
		{
			get { return default(T); }
		}

		bool ICheckable.Apply()
		{
			return false;
		}
	}
}